#include "stdafx.h"
#include "ObjectManager.h"
#include "GameObject.h"
#include "../../EdgeMath/IBoundingShape.h"
#include "../World/WorldEvents.h"
#include "IAgent.h"
#include "Player\Player.h"

ObjectManager::ObjectManager(void)
{
}

/*virtual*/ ObjectManager::~ObjectManager(void)
{
	// release all objects
	for (unsigned int i = 0; i < objects.size(); i++)
		objects[i]->Release(); 
	// release all agents
	for (unsigned int i = 0; i < agents.size(); i++)
		agents[i]->Release();
}

/////////////////////<abstract functions>//////////////////////////////////////////

/*virtual*/ void ObjectManager::Update(float dt) /*override*/
{

	// update all objects
	for (unsigned int i = 0; i < objects.size(); i++)
	{
		objects[i]->Update(dt);
		/***********************Temporary********************************/
		if (objects[i]->getCollider())
		{
			for (unsigned int ii = 0; ii < objects.size(); ii++)
			{
				if (ii == i)
					continue;
				IBoundingShape* collider = objects[ii]->getCollider();
				if (collider && objects[i]->getCollider()->Intersects(collider))
				{
					void* prams1[] =
					{
						objects[i],
						objects[ii],
					};
					objects[i]->OnCollision(prams1);

					// switch the order of params
					prams1[0] = (void*)objects[ii];
					prams1[1] = (void*)objects[i];
					objects[ii]->OnCollision(prams1);
				}
			}
		}
		/****************************************************************/
	}
	// update all agents
	for (unsigned int i = 0; i < agents.size(); i++)
		agents[i]->Update(dt);
}

/*virtual*/ void ObjectManager::Draw(void) /*override*/
{
	// draw all objects
	for (unsigned int i = 0; i < objects.size(); i++)
		objects[i]->Draw();
}

/////////////////////<public functions>//////////////////////////////////////////

void ObjectManager::AddObject(GameObject* object)
{
	// add reference to the object, and add it to the collection
	object->AddRef();
	objects.push_back(object);
	// raise the AddObject event
	GameObject* params[1] = { object };
	WorldEvents::ObjectCreated->Invoke((void**)params);
}

void ObjectManager::AddAgent(Agent* agent)
{
	agent->AddRef();
	agents.push_back(agent);
}

bool ObjectManager::RemoveObject(GameObject* object)
{
	// check to see if any of the objects are the prameter
	for (unsigned int i = 0; i < objects.size(); i++)
	{
		if (object == objects[i])
		{
			// raise the object removed event
			GameObject* params[1] = { object };
			WorldEvents::ObjectDestroyed->Invoke((void**)params);
			// release the object before removing it
			objects[i]->Release();
			objects.erase(objects.begin() + i);
			// match found, return true
			return true;
		}
	}

	// no match retun false
	return false;
}

void ObjectManager::RemoveAt(int index)
{
	// ensure the provided index is within bounds
	if (index >= (int)objects.size() || index < 0)
		return;

	// raise object removed event
	GameObject* params[1] = { objects[index] };
	WorldEvents::ObjectDestroyed->Invoke((void**)params);

	// release object before deleting
	objects[index]->Release();
	objects.erase(objects.begin() + index);
}